package com.may.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.may.shiro.realm.CustomerRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * shior框架相关配置
 * @author mayuanbao
 * @date 2020-07-10 20:49
 */
@Configuration
public class ShiroConfig {

    /**
     * 创建shiroFilter，负责拦截所有请求
     * @author mayuanbao
     * @date 2020/11/04 14:50
     * @param defaultWebSecurityManager defaultWebSecurityManager
     * @return org.apache.shiro.spring.web.ShiroFilterFactoryBean
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        // 给filter设置安全管理器
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
        // 配置系统受限资源、公共资源，authc 请求这个资源需要认证和授权
        Map<String, String> map = new LinkedHashMap<>();
        map.put("/favicon.ico", "anon");
        map.put("/static/**", "anon");
        map.put("/toRegister", "anon");
        map.put("/register", "anon");
        map.put("/login", "anon");
        map.put("/**", "authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        // 设置默认登录界面路径
        shiroFilterFactoryBean.setLoginUrl("/login");
        return shiroFilterFactoryBean;
    }

    /**
     * 创建安全管理器
     * @author mayuanbao
     * @date 2020/11/04 14:50
     * @param customerRealm customerRealm
     * @return org.apache.shiro.web.mgt.DefaultWebSecurityManager
     */
    @Bean
    public DefaultWebSecurityManager defaultWebSecurityManager(CustomerRealm customerRealm) {
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        // 给安全管理器设置realm
        defaultWebSecurityManager.setRealm(customerRealm);
        return defaultWebSecurityManager;
    }

    /**
     * 创建自定义realm
     * @author mayuanbao
     * @date 2020/11/04 14:51
     * @return com.may.shiro.realm.AccountRealm
     */
    @Bean
    public CustomerRealm customerRealm() {
        CustomerRealm customerRealm = new CustomerRealm();
        // 修改凭证校验匹配器
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        // 设置加密算法为md5
        credentialsMatcher.setHashAlgorithmName("MD5");
        // 设置散列次数
        credentialsMatcher.setHashIterations(1024);
        // 设置凭证校验匹配器
        customerRealm.setCredentialsMatcher(credentialsMatcher);
        // 开启缓存管理
        customerRealm.setCacheManager(new EhCacheManager());
        // 开启全局缓存
        customerRealm.setCachingEnabled(true);
        // 开启认证缓存
        customerRealm.setAuthenticationCachingEnabled(true);
        customerRealm.setAuthenticationCacheName("authenticationCache");
        // 开启授权缓存
        customerRealm.setAuthorizationCachingEnabled(true);
        customerRealm.setAuthorizationCacheName("authorizationCache");
        return customerRealm;
    }

    /**
     * 在thymeleaf中使用shiro的自定义tag
     * @author mayuanbao
     * @date 2020/11/07 9:16
     * @return at.pollux.thymeleaf.shiro.dialect.ShiroDialect
     */
    @Bean(name = "shiroDialect")
    public ShiroDialect shiroDialect() {
        return new ShiroDialect();
    }
}
